package net.pimpas.web.jsf.components.simplemenu;

import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseId;

import net.pimpas.web.jsf.components.UIComponentPimpasBase;
import net.pimpas.web.jsf.util.ComponentInformation;

public class UISimpleMenu extends UIComponentPimpasBase {

	public static final String COMPONENT_TYPE			 = ComponentInformation.COMPONENT_PREFIX_TYPE+".simplemenu";
	public static final String COMPONENT_FAMILY			 = ComponentInformation.COMPONENT_PREFIX_FAMILY+".simplemenu";
	public static final String COMPONENT_RENDER_TYPE	 = ComponentInformation.COMPONENT_PREFIX_RENDER+".simplemenu";
	public static final String[] THEMES					 = {
															"default","windows"
														   };
	public static final String[] DEFAULT_STYLE_FILES	 = {
															 "simplemenu.css", "simplemenu.windows.css"
														   };
	public static final Integer DEFAULT_THEME_INDEX		 = 0;
	public static final Integer DEFAULT_WIDTH			 = 15;
	public static final Integer DEFAULT_HEIGHT			 = 18;
	public static final String DEFAULT_SUFIX_ROOT_MENU	 = "_root";
	public static final String DEFAULT_SUFIX_MENU_BAR	 = "_bar";
	public static final String DEFAULT_SUFIX_BUTTON		 = "_button_access";
	public static final String DEFAULT_SUFX_CONTAINER	 = "_menu_container";
	public static final String DEFAULT_JS_FILE 			 = "simplemenu.js";
	public static final String DEFAULT_SUFIX_ITEM_ACCESS = "_item_access";
	public static final String DEFAULT_SUFIX_HIDDEN 	 = "_hidden";
	public static final String MENU_ITEM_CLICKED		 = "ComponentMenuItemClicked";
	
	private String theme;
	private String onMenuItemClicked;
	private Integer width;
	private Integer height;
	
	@Override
	public Object saveState(FacesContext context) {
		Object[] ob = new Object[5];
		ob[0] = super.saveState(context);
		ob[1] = this.getTheme();
		ob[2] = this.getOnMenuItemClicked();
		ob[3] = this.getWidth();
		ob[4] = this.getHeight();
		
		return ob;
	}
	
	@Override
	public void restoreState(FacesContext context, Object state) {
		Object[] ob = (Object[]) state;
		super.restoreState(context, ob[0]);
		this.setTheme((String) ob[1]);
		this.setOnMenuItemClicked((String) ob[2]);
		this.setWidth((Integer) ob[3]);
		this.setHeight((Integer) ob[4]);
		
	}
	

	@Override
	public boolean getRendersChildren() {
		return true;
	}
	
	@Override
	public String getRendererType() {
		return COMPONENT_RENDER_TYPE;
	}

	@Override
	public String getFamily() {
		return COMPONENT_FAMILY;
	}

	public String getTheme() {
		return theme;
	}

	public void setTheme(String theme) {
		this.theme = theme;
	}

	public String getOnMenuItemClicked() {
		return onMenuItemClicked;
	}

	public void setOnMenuItemClicked(String onMenuItemClicked) {
		this.onMenuItemClicked = onMenuItemClicked;
	}

	public Integer getHeight() {
		return height;
	}

	public void setHeight(Integer height) {
		this.height = height;
	}

	public Integer getWidth() {
		return width;
	}

	public void setWidth(Integer width) {
		this.width = width;
	}
	
	@Override
	public void queueEvent(FacesEvent event) {
		event.setPhaseId(PhaseId.INVOKE_APPLICATION);
		super.queueEvent(event);
	}
	
	@Override
	public void broadcast(FacesEvent event) throws AbortProcessingException {
		// process onMenuItemClicked
		String outcome = (String) event.getComponent().getAttributes().remove(MENU_ITEM_CLICKED);
		if(this.getOnMenuItemClicked()!=null && !"".equals(this.getOnMenuItemClicked())) {
			MethodBinding mb = FacesContext.getCurrentInstance().getApplication().createMethodBinding(this.getOnMenuItemClicked(), new Class[]{String.class});
			String result = (String) mb.invoke(FacesContext.getCurrentInstance(), new Object[]{outcome});
			if(result == null)
				// process
				this.processOutcomeMessage(outcome);
			else
				this.processOutcomeMessage(result);
		}
		else
			this.processOutcomeMessage(outcome);
	}
	
	private void processOutcomeMessage( String outcome ) {
		FacesContext context = FacesContext.getCurrentInstance();
		String fromAction = context.getViewRoot().getViewId();
        NavigationHandler navigationHandler = context.getApplication().getNavigationHandler();
        navigationHandler.handleNavigation(context,
                                           fromAction,
                                           outcome);
		//Render Response if needed
		context.renderResponse();
	}
}